﻿using System;
using System.Globalization;

namespace SocialApi.Core.Extensions
{
    /// <summary>
    /// Пользовательские расширения
    /// </summary>
    public static class Extension
    {
        /// <summary>
        /// Преобразует один тип в другой
        /// </summary>
        /// <typeparam name="T">Новый тип</typeparam>
        /// <param name="data">Объект, который преобразуется</param>
        /// <returns>Объект в новом типе</returns>
        public static T ConvertTo<T>(this object data)
            where T : IConvertible
        {
            if (typeof(T).GetInterface("System.IConvertible") != typeof(IConvertible))
            {
                throw new Exception("Объект должен наследоваться от \"System.IConvertible\"");
            }
            return (T)Convert.ChangeType(data, typeof(T));
        }

        /// <summary>
        /// Проверяет, существует объект или нет
        /// </summary>
        /// <param name="data">Проверяемый объект</param>
        /// <returns>True, если объект сусещствует</returns>
        public static bool Exists(this object data)
        {
            if (data is string)
            {
#if NET_4_5 || NET_4_0
                return !string.IsNullOrWhiteSpace(data.ToString());
#else
                return !string.IsNullOrEmpty(data.ToString());
#endif
            }
            if (data is sbyte)
            {
                return data.ConvertTo<sbyte>() != -1;
            }
            if (data is short)
            {
                return data.ConvertTo<short>() != -1;
            }
            if (data is int)
            {
                return data.ConvertTo<int>() != -1;
            }
            if (data is long)
            {
                return data.ConvertTo<long>() != -1;
            }
            if (data is float)
            {
                return data.ConvertTo<float>() != -1;
            }
            if (data is double)
            {
                return data.ConvertTo<double>() != -1;
            }
            if (data is byte)
            {
                return data.ConvertTo<byte>() != 0;
            }
            if (data is uint)
            {
                return data.ConvertTo<uint>() != 0;
            }
            if (data is ushort)
            {
                return data.ConvertTo<ushort>() != 0;
            }
            if (data is ulong)
            {
                return data.ConvertTo<ulong>() != 0;
            }
            if (data is decimal)
            {
                return data.ConvertTo<decimal>() != 0;
            }
            return data != null;
        }

        /// <summary>
        /// Возвращает строку не зависящую от языка и региональных параметров
        /// </summary>
        /// <param name="data">Объект, который преобразуем в строку</param>
        /// <returns>Строка не зависящая от языка и региональных параметров</returns>
        public static string ToInvariantString(this object data)
        {
            return string.Format(CultureInfo.InvariantCulture, "{0}", data);
        }
        
        /// <summary>
        /// Преобразует UNIX формат времени в <see cref="DateTime"/>
        /// </summary>
        /// <param name="unixTimeStamp">Время, в UNIX формате</param>
        /// <returns>Время, в <see cref="DateTime"/></returns>
        public static DateTime ToDateTimeTimestamp(this double unixTimeStamp)
        {
            return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(unixTimeStamp).ToLocalTime();
        }

        /// <summary>
        /// Преобразует <see cref="DateTime"/> формат в UNIX
        /// </summary>
        /// <param name="dateTime">Время, в <see cref="DateTime"/></param>
        /// <returns>Время, в UNIX формате</returns>
        public static double ToUnixTimestamp(this DateTime dateTime)
        {
            return (dateTime - new DateTime(1970, 1, 1).ToLocalTime()).TotalSeconds;
        }
    }
}